package com.example.leavemanagement.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.example.leavemanagement.exception.BusinessException;
import com.example.leavemanagement.exception.ErrorCode;
import com.example.leavemanagement.exception.ThrowUtils;
import com.example.leavemanagement.mapper.LeaveInfoMapper;
import com.example.leavemanagement.model.dto.leave.LeaveAddRequest;
import com.example.leavemanagement.model.dto.leave.LeaveQueryRequest;
import com.example.leavemanagement.model.dto.leave.LeaveReviewRequest;
import com.example.leavemanagement.model.entity.LeaveInfo;
import com.example.leavemanagement.model.entity.User;
import com.example.leavemanagement.model.enums.LeaveReviewStatusEnum;
import com.example.leavemanagement.model.enums.UserRoleEnum;
import com.example.leavemanagement.model.vo.LeaveVo;
import com.example.leavemanagement.model.vo.UserVo;
import com.example.leavemanagement.service.LeaveInfoService;
import com.example.leavemanagement.service.UserService;
import com.fasterxml.jackson.annotation.JsonUnwrapped;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @author 炼金术士
 * @description 针对表【leave_info(请假信息)】的数据库操作Service实现
 * @createDate 2025-04-28 12:20:06
 */
@Service
@Slf4j
public class LeaveInfoServiceImpl extends ServiceImpl<LeaveInfoMapper, LeaveInfo>
        implements LeaveInfoService {

    @Resource
    UserService userService;

    @Override
    public boolean addLeaveInfo(LeaveAddRequest leaveAddRequest, HttpServletRequest request) {
        String name = leaveAddRequest.getName();
        User loginUser = userService.getLoginUser(request);
        if (!loginUser.getUserName().equals(name)) {
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR,"请假人和实际用户不匹配");
        }
        LeaveInfo leaveInfo = new LeaveInfo();
        leaveInfo.setUserId(loginUser.getId());
        leaveInfo.setLeaveReason(leaveAddRequest.getLeaveReason());
        leaveInfo.setCategory(leaveAddRequest.getCategory());
        leaveInfo.setName(leaveAddRequest.getName());
        leaveInfo.setAddress(leaveAddRequest.getAddress());
        leaveInfo.setSection(leaveAddRequest.getSection());
        return this.save(leaveInfo);
    }

    @Override
    public QueryWrapper<LeaveInfo> getQueryWrapper(LeaveQueryRequest leaveQueryRequest) {
        QueryWrapper<LeaveInfo> queryWrapper = new QueryWrapper<>();
        Long id = leaveQueryRequest.getId();
        String leaveReason = leaveQueryRequest.getLeaveReason();
        String name = leaveQueryRequest.getName();
        String category = leaveQueryRequest.getCategory();
        String address=leaveQueryRequest.getAddress();
        Long userId = leaveQueryRequest.getUserId();
        Integer isDelete = leaveQueryRequest.getIsDelete();
        Integer reviewStatus = leaveQueryRequest.getReviewStatus();
        String reviewMessage = leaveQueryRequest.getReviewMessage();
        Long reviewerId = leaveQueryRequest.getReviewerId();
        Date reviewTime = leaveQueryRequest.getReviewTime();
        String section = leaveQueryRequest.getSection();
        Integer spaceId = leaveQueryRequest.getSpaceId();

        queryWrapper.eq(StrUtil.isNotEmpty(leaveReason), "leaveReason", leaveReason);
        queryWrapper.eq(StrUtil.isNotEmpty(name), "name", name);
        queryWrapper.like(StrUtil.isNotBlank(category), "category", category);
        queryWrapper.eq(StrUtil.isNotEmpty(section), "section", section);
        queryWrapper.eq(StrUtil.isNotEmpty(reviewMessage), "reviewMessage", reviewMessage);
        queryWrapper.eq(ObjUtil.isNotEmpty(reviewerId), "reviewerId", reviewerId);
        queryWrapper.eq(ObjUtil.isNotEmpty(reviewTime), "reviewTime", reviewTime);
        queryWrapper.eq(ObjUtil.isNotEmpty(spaceId), "spaceId", spaceId);
        queryWrapper.eq(ObjUtil.isNotEmpty(isDelete), "isDelete", isDelete);
        queryWrapper.eq(ObjUtil.isNotEmpty(reviewStatus), "reviewStatus", reviewStatus);
        queryWrapper.eq(ObjUtil.isNotEmpty(userId), "userId", userId);
        queryWrapper.eq(ObjUtil.isNotEmpty(id), "id", id);
        queryWrapper.eq(StrUtil.isNotEmpty(address),"address",address);
        return queryWrapper;
    }

    @Override
    public void doLeaveReview(LeaveReviewRequest leaveReviewRequest, User loginUser) {
        ThrowUtils.throwIf(!loginUser.getUserRole().equals(UserRoleEnum.ADMIN.getValue()),ErrorCode.NO_AUTH_ERROR);
        Long id = leaveReviewRequest.getId();
        Integer reviewStatus = leaveReviewRequest.getReviewStatus();
        String reviewMessage = leaveReviewRequest.getReviewMessage();
        LeaveInfo oldLeaveInfo = this.getById(id);
        ThrowUtils.throwIf(oldLeaveInfo==null,ErrorCode.NOT_FOUND_ERROR,"未找到对应的请假信息");
        if(Objects.equals(oldLeaveInfo.getReviewStatus(), reviewStatus)){
            throw new BusinessException(ErrorCode.NO_AUTH_ERROR,"请勿重复审核");
        }
        LeaveReviewStatusEnum leaveReview = LeaveReviewStatusEnum.getEnumByValue(reviewStatus);
        ThrowUtils.throwIf(leaveReview==null,ErrorCode.NOT_FOUND_ERROR,"未找到对应的审核状态");
        LeaveInfo updateLeaveInfo=new LeaveInfo();
        BeanUtil.copyProperties(leaveReviewRequest,updateLeaveInfo);
        updateLeaveInfo.setReviewTime(new Date());
        updateLeaveInfo.setReviewerId(loginUser.getId());
        boolean result = this.updateById(updateLeaveInfo);
        ThrowUtils.throwIf(!result,ErrorCode.OPERATION_ERROR);
    }

    @Override
    public List<LeaveVo> getUserLeaveInfoList(User loginUser) {
        QueryWrapper<LeaveInfo> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("userId",loginUser.getId());
        queryWrapper.eq("isDelete",0);
        List<LeaveInfo> leaveInfoList = this.list(queryWrapper);
        List<LeaveVo> leaveInfoVoList = BeanUtil.copyToList(leaveInfoList, LeaveVo.class);
        leaveInfoVoList.forEach(leaveInfoVo -> {
            Long userId = leaveInfoVo.getUserId();
            User Reviewer = userService.getById(userId);
            if(Reviewer!=null){
                UserVo userVo = userService.getUserVo(Reviewer);
                leaveInfoVo.setUser(userVo);
            }
        });
        return leaveInfoVoList;
    }
}





